/*
* 2、
*（1）IP以字符串输入存在 unsigned int中
* (2) 传入 unsigned int的值，以点分十进制样式输出   
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BIG 1
#define SMALL 0
#define TYPE_ERROR -1
#define IP_MAXLENGTH 16

unsigned int str2uint(char * ip);       //输入的字符串转无符号整型
char* uint2str(unsigned int sum);       //无符号整型转点分十进制IP，保证不受大小端影响
int StorageAtBigOrsmall(void);          //判断计算机的存储类型是大端序还是小端序

union IP {
    unsigned char char_ip[4];
    unsigned int uint_ip;
};

int main() {
    char str[IP_MAXLENGTH]="";
    printf("Please enter the ip address,For example, 192.168.0.1:");
    scanf("%s", str);

    unsigned int ipnumber = str2uint(str);

    printf("OutPut: %s \n", uint2str(ipnumber));

    return 0;
}

unsigned int str2uint(char * ip) {
    if(ip == NULL) {
        return 0;
    }
    unsigned int utable[4];
    int iPosition = 0;
    int n = strlen(ip);
    char* pFast = ip; 
    char* pSlow = ip;
    for(int i = 0; i < n; i++) {
        if(*pFast == '.' || i == n - 1) {
            int len = pFast - pSlow;
            if(i == n - 1) {
                len++;
            }
            char temp[3] = {0};
            strncpy(temp,pSlow, len);
            utable[iPosition] = atoi(temp);
            iPosition++;
            pFast++;
            pSlow = pFast;
        }else {
            pFast++;
        }
    }
    unsigned int sum = utable[0]*256*256*256 + utable[1]*256*256 + utable[2]*256 + utable[3];

    return sum;
}

char* uint2str(unsigned int sum) {
    union IP ip;
    ip.uint_ip = sum;
    char * strip= (char*)malloc(IP_MAXLENGTH);
    memset(strip,0,IP_MAXLENGTH);

    int StorgeType = StorageAtBigOrsmall();   //为保证任何机器都能按照输入的IP输出原样，这里对大小端机器做判断
    if(StorgeType == TYPE_ERROR) {
        printf("Unable to recognize!");
        return NULL;
    }

    int iSequence = 0;
    for(int i = 3;i >= 0;i--)
    {
        iSequence = i;          //小端存储就从高地址开始取
        if(StorgeType) {
            iSequence = 3 - i;  //大端存储则相反
        }
        char tmp[4]="";
        itoa(ip.char_ip[iSequence],tmp,10);
        strcat(strip,tmp);
        if(i > 0)
        {
            char *dot=".";
            strcat(strip,dot);
        }
    }

    return strip;
}

int StorageAtBigOrsmall(void) {
    //判断计算机的存储类型是大端序还是小端序
    union IP systest;
    systest.uint_ip = 0x12345678;
    if(systest.char_ip[0] == 0x12) {
        return BIG;
    } else if(systest.char_ip[0] == 0x78) {
        return SMALL;
    }else {
        return TYPE_ERROR;
    }
}